import datetime
import os
import sys
import atexit
from selenium import webdriver
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.edge.options import Options
from selenium.webdriver.edge.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import ddddocr
import time

def singleton(cls):
    """单例模式装饰器（复用你的实现）"""
    _instance = {}

    def wrapper(*args, **kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)
        return _instance[cls]

    return wrapper


@singleton  # 应用单例模式，确保全局唯一实例
class EdgeDriver:
    def __init__(self):
        # 手动指定Edge驱动路径（与你的路径格式一致）
        self.driver_path = r"D:\Edge驱动\edgedriver_win64\msedgedriver.exe"  # 可替换为你的实际路径
        self.driver = None  # 初始化驱动实例为None
        self.init_driver()  # 调用初始化方法

    def init_driver(self):
        """初始化Edge浏览器驱动（完整流程）"""
        # 1. 校验驱动路径是否存在（避免文件未找到错误）
        if not os.path.exists(self.driver_path):
            raise FileNotFoundError(f"Edge驱动文件不存在：{self.driver_path}")

        # 2. 配置Edge浏览器选项（复用你的核心配置）
        edge_options = Options()
        edge_options.add_argument("--remote-allow-origins=*")  # 解决跨域问题
        edge_options.add_argument("--disable-blink-features=AutomationControlled")  # 隐藏自动化标识
        edge_options.add_argument("--start-maximized")  # 窗口最大化
        # 可选：如需无头模式，可添加以下配置
        # edge_options.add_argument("--headless=new")

        # 3. 创建驱动实例（指定服务和选项）
        self.driver = webdriver.Edge(
            service=Service(self.driver_path),  # 传入手动指定的驱动路径
            options=edge_options
        )

        # 4. 设置隐式等待（全局元素等待时间）
        self.driver.implicitly_wait(5)

        # 5. 注册程序退出时自动关闭驱动（确保资源释放）
        atexit.register(self.quit_driver)
    def captcha(self):
        """验证码识别（之前遗漏的方法，补全）"""
        ocr = ddddocr.DdddOcr(show_ad=False)
        # 等待验证码元素加载
        captcha_ele = WebDriverWait(self.driver, 10).until(
            EC.visibility_of_element_located((By.XPATH, '//*[@id="form-verify-img"]'))
        )
        captcha_bytes = captcha_ele.screenshot_as_png
        captcha_text = ocr.classification(captcha_bytes)
        # 输入验证码
        captcha_input = WebDriverWait(self.driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, '//*[@type="text" and @name="verify"]'))
        )
        captcha_input.send_keys(captcha_text)
        print(f"识别到验证码：{captcha_text}")
    def Auto_Login(self):
            # 1. 点击登录入口
            login_entry = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div[1]/div[6]/div/div[1]/div[2]/a[1]"))
            )
            login_entry.click()

            # 2. 输入用户名
            username_ele = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div[1]/div[3]/div/div[2]/div[2]/div[2]/div/div[1]/div[1]/form/div[1]/input"))
            )
            username_ele.send_keys("zzz111")

            # 3. 输入密码
            password_ele = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div[1]/div[3]/div/div[2]/div[2]/div[2]/div/div[1]/div[1]/form/div[2]/input"))
            )
            password_ele.send_keys("zzz123")

            # 4. 处理验证码
            self.captcha()

            # 5. 点击登录按钮
            login_btn = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div[1]/div[3]/div/div[2]/div[2]/div[2]/div/div[1]/div[1]/form/div[4]/button"))
            )
            login_btn.click()
            time.sleep(2)
    def GetScreenShot(self, custom_name=""):
        """屏幕截图功能"""
        try:
            # 构建截图保存路径（基于当前文件位置的上层images文件夹）
            base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../images"))
            dirname = datetime.datetime.now().strftime("%Y-%m-%d")  # 按日期分类
            save_dir = os.path.join(base_dir, dirname)

            # 确保文件夹存在（不存在则创建，支持多级目录）
            os.makedirs(save_dir, exist_ok=True)

            # 生成截图文件名（调用函数名+时间戳+自定义名称）
            time_str = datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S")
            caller_name = sys._getframe().f_back.f_code.co_name  # 获取调用该方法的函数名
            filename = f"{caller_name}-{time_str}"
            if custom_name:
                filename += f"-{custom_name}"  # 追加自定义后缀
            filename += ".png"  # 补全后缀

            # 保存截图并返回路径
            save_path = os.path.join(save_dir, filename)
            self.driver.save_screenshot(save_path)
            print(f"截图成功，保存路径：{save_path}")
            return save_path
        except Exception as e:
            print(f"截图失败：{str(e)}")
            return None

    def ClearInput(self, element):
        """清空输入框"""
        actions = ActionChains(self.driver)
        actions.click(element)  # 点击激活输入框
        actions.key_down(Keys.CONTROL).send_keys("a").key_up(Keys.CONTROL)  # Ctrl+A全选
        actions.send_keys(Keys.DELETE)  # 删除选中内容
        actions.perform()  # 执行所有动作
    def quit_driver(self):
        """安全关闭浏览器驱动（确保程序退出时释放资源）"""
        if hasattr(self, "driver") and self.driver:
            try:
                self.driver.quit()
                print("Edge浏览器已安全关闭")
            except Exception as e:
                print(f"关闭浏览器失败：{str(e)}")


# 创建单例实例（全局唯一，所有地方通过该实例调用）
SHPDriver = EdgeDriver()